package com.dongdongshop.service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.dongdongshop.pojo.cart.Cart;
import com.dongdongshop.pojo.order.TbOrderItem;
import com.dongdongshop.pojo.seller.TbItem;
import com.dongdongshop.service.cart.CartServiceI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

@Component//放到容器中
@Service//dubbo暴露接口
public class CartServiceImpl implements CartServiceI {
    @Reference
    private ItemService itemService;
    @Autowired
    private RedisTemplate redisTemplate;

      //添加购物车业务逻辑
    @Override
    public List<Cart> addCartList(List<Cart> cartList, Long itemId, Integer num) {
        //原来购物车数据 cartList
        //1.根据传来的itemId商品id查出商品的数据
        TbItem tbItem =itemService.getItemById(itemId);
        if (tbItem ==null){
            throw new RuntimeException("商品不存在");//抛异常
        }
        if (!"1".equals(tbItem.getStatus())){
            throw new RuntimeException("商品不存在1");
        }
        //2.获取商家的id（sellerid）
        String sellerId = tbItem.getSellerId();
        //3.根据商家id去判断，判断原来购物车中有没有当前商家的购物车
       /* for (Cart cart : cartList) {//遍历原来得购物车 抽取方法在getCartBySellerId()里
            Objects.equals(cart.getSellerId(),sellerId);//判断两个数据是否相等不会有空指针问题
        }*/
        Cart cart = getCartBySellerId(cartList, sellerId);//封装得方法
        //4.如果没有该商家的购物车
        if (cart == null){
            //4.1 创建新的cart对象
            cart=new Cart();
            cart.setSellerId(sellerId);
            cart.setSellerName(tbItem.getSeller());
            //保存信息
            List<TbOrderItem> orderItemList=new ArrayList<>();
            //添加购物车明细
            TbOrderItem orderItem = creatTbOrderItemByItem(tbItem, num);//在下面封装方法里
            //讲购物车明细添加到列表中
            orderItemList.add(orderItem);
            //将购物车明细列表，存放到购物车中
            cart.setOrderItemList(orderItemList);
            //4.2 讲cart对象add到原来的购物车列表cartList中
                cartList.add(cart);
            }else {//5. 如果原购物车中存在该商家的购物车
            //6. 根据当前的商品信息，查询购物车明细表中是否存在该商品
                TbOrderItem orderItem = getTbOrderItemByItemId(cart.getOrderItemList(), itemId);
                if (orderItem == null){
                    //6.1 如果不存在 创建心得TbOrderItem对象，并且新增到orderItemList中
                    orderItem=creatTbOrderItemByItem(tbItem, num);
                    cart.getOrderItemList().add(orderItem);//生成得明细对象放到已有得明细列表中
                }else {
                    //6.2 如果存在 在原来得购物车明细上添加数量，更改金额
                    orderItem.setNum(orderItem.getNum() + num);//原来数量+现在提交得数量
                    //计算单价 总数量*单价
                    orderItem.setTotalFee(new BigDecimal(orderItem.getNum()*tbItem.getPrice().doubleValue()));
                    //如果操作后购买数量小于等于0，需要移除购物车明细
                    if (orderItem.getNum() <= 0){
                        cart.getOrderItemList().remove(orderItem);//移除购物车数据
                    }
                    //如果移除完之后，购物车明细列表中没有数据了，我们需要将购物车对象移除
                    if (cart.getOrderItemList().isEmpty()){//对象为空
                        cartList.remove(cart);
                    }
                }
        }

          return cartList;
    }

    //根据商家id查询购物车实体
    private Cart getCartBySellerId(List<Cart> cartList,String sellerId){
        for (Cart cart : cartList) {
            if (Objects.equals(cart.getSellerId(),sellerId)){
                return cart;
            }
        }
        return null;
    }

    //根据itemId 查询购物车明细列表中是否存在该商品
    private TbOrderItem getTbOrderItemByItemId(List<TbOrderItem> orderItemList,Long itemId){
        for (TbOrderItem orderItem : orderItemList) {
            if (Objects.equals(orderItem.getItemId(),itemId)){
                return orderItem;
            }
        }
        return null;
    }


    //根据商品SKU 和购买数量 生成订单明细对象
    public TbOrderItem creatTbOrderItemByItem(TbItem tbItem,Integer num){
        TbOrderItem orderItem=new TbOrderItem();
        orderItem.setNum(num);
        orderItem.setTitle(tbItem.getTitle());
        orderItem.setTotalFee(new BigDecimal(num*tbItem.getPrice().doubleValue()));
        orderItem.setPrice(tbItem.getPrice());
        orderItem.setPicPath(tbItem.getImage());
        orderItem.setItemId(tbItem.getId());
        orderItem.setGoodsId(tbItem.getGoodsId());
        orderItem.setSellerId(tbItem.getSellerId());
        return orderItem;
    }

    //从redis中查询购物车数据
    @Override
    public List<Cart> getCartListFromRedis(String userName) {
        List<Cart> cartList =(List<Cart>) redisTemplate.boundHashOps("cartList").get(userName);
        Optional<List<Cart>> optional=Optional.ofNullable(cartList);
        return optional.orElse(new ArrayList<>());//如果为空就创建个
    }


    //向redis中存储购物车
    @Override
    public void saveCartListToRedis(String username, List<Cart> list) {
        redisTemplate.boundHashOps("cartList").put(username,list);
    }

    //合并购物车，讲cookie中方得list与redis中得list进行合并
    @Override
    public List<Cart> mergeCartListCookieAndRedis(List<Cart> cookieList, List<Cart> redisList) {
       //登录之后讲cookie数据添加到redis中，有相同得数据改变数量，没有就加入
        //1.遍历大购物车， 里面有list明细列表 要合并得是购物车列表中得每一个购物车明细
        for (Cart cart : cookieList) {
            //遍历大购物车里明细，进行合并
            for (TbOrderItem orderItem : cart.getOrderItemList()) {
                redisList=  addCartList(redisList,orderItem.getItemId(),orderItem.getNum());//同上面添加购物车得逻辑一样
            }
        }
        return redisList;
    }


}
